import logging

import colorlog

LOG_COLOR = {
    "DEBUG": "blue",
    "INFO": "white",
    "WARNING": "yellow",
    "ERROR": "red",
    "CRITICAL": "bold_red"
}

_logger_root: logging.Logger | None = None
_logger_cache: dict[str, logging.Logger] = {}

def get_logger(
    name: str | None = None,
    level: int | str = logging.INFO,
    fmt: str = "%(log_color)s %(asctime)s %(levelname)s %(message)s",
    datefmt: str = "%H:%M:%S"
) -> logging.Logger:
    """Return a logger with the specified name, creating it if necessary.
    
    If no name is specified, return the root logger.    
    """
    
    global _logger_root, _logger_cache
    
    if name is None:
        if _logger_root: return _logger_root
        
    else:
        lg = _logger_cache.get(name)
        if lg: return lg
    
    # Create a logger
    if name is None:
        logger = logging.getLogger("RootLogger@vEngine")
    else:
        logger = logging.getLogger(name)
    logger.setLevel(level)
    
    console_handler = logging.StreamHandler()
    console_handler.setLevel(level)
    
    console_formatter = colorlog.ColoredFormatter(
        fmt = fmt,
        datefmt = datefmt,
        log_colors = LOG_COLOR
    )
    console_handler.setFormatter(console_formatter)
    
    if not logger.handlers:
        logger.addHandler(console_handler)
    console_handler.close()
    
    if name is None:
        _logger_root = logger
    else:
        _logger_cache[name] = logger
        
    return logger